/**
 * \file BloomFilterHashFunctions.h
 * \brief Depends on: MurmurHash.h, MurmurHash.cpp
 */

#ifndef __KEY_VALUE_FILE_BLOOM_FILTER_HASH_FUNCTIONS_H_
#define __KEY_VALUE_FILE_BLOOM_FILTER_HASH_FUNCTIONS_H_

#include <stdlib.h>
#include "MurmurHash.h"


namespace KeyValueFile
{
	/**
	 * \brief Template functor to calculate hash of POD (plain old data) type, every instance of this class will produce different hash values due to random seed
	 */
	template< typename PodType >
	class BloomFilterMurmurHashPOD
	{
	public:
		/**
		 * \brief Constructor initializes random seed
		 */
		BloomFilterMurmurHashPOD( ) :
			m_seed( rand( ) )
		{
		}

		/**
		 * \brief Calculates Murmur hash of POD (plain old data) type with random seed
		 */
		unsigned int operator( )( const PodType& obj ) const
		{
			const unsigned int MinMurmurLength = 16;
			if( sizeof( PodType ) < MinMurmurLength )
			{
				const unsigned int NumElements = MinMurmurLength / sizeof( PodType ) + 1;

				PodType a[ NumElements ];
				for( unsigned int i = 0; i < NumElements; ++i )
					memcpy( &a[ i ], &obj, sizeof( PodType ) );

				return MurmurHash2( a, sizeof( PodType ) * NumElements, m_seed );
			}
			else
			{
				return MurmurHash2( &obj, sizeof( PodType ), m_seed );
			}
		}

	private:
		unsigned int m_seed;
	};
};

#endif